﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.ComponentModel.Composition;

using NuMetaheuristics;
using NuMetaheuristics.Genotypes;
using NuMetaheuristics.Operators.Value;

using MathNet.Numerics.Random;

namespace NuMetaheuristics.Operators.Vector
{
    /// <summary>
    /// Initialize each element of a vector with the given value initializer.
    /// </summary>
    [DataContract(Namespace = "http://numetaheuristics.codeplex.com/schemas")]
    [Export(typeof(IUnaryOperator<DoubleVectorGenotype>))]
    public class DoubleVectorInitializer : IUnaryOperator<DoubleVectorGenotype>
    {
        [DataMember]
        private DoubleRandomInitializer _valueInitializer;

        public DoubleVectorInitializer()
        {
        }
        
        public DoubleVectorInitializer(DoubleRandomInitializer valueInitializer)
        {
            _valueInitializer = valueInitializer;
        }

        public void Operate(ref DoubleVectorGenotype operand)
        {
            if (_valueInitializer == null)
                throw new NullReferenceException();

            if (operand == null)
                throw new ArgumentNullException();

            for(int i = 0; i < operand.Vector.Length; i++)
            {
                _valueInitializer.Operate(ref operand.Vector[i]);
            }
        }
    }

    /// <summary>
    /// Initialize each element of a vector with the given value initializer.
    /// </summary>
    [DataContract(Namespace = "http://numetaheuristics.codeplex.com/schemas")]
    [Export(typeof(IUnaryOperator<IntegerVectorGenotype>))]
    public class IntegerVectorInitializer : IUnaryOperator<IntegerVectorGenotype>
    {
        [DataMember]
        private IntegerRandomInitializer _valueInitializer;

        public IntegerVectorInitializer()
        {
        }

        public IntegerVectorInitializer(IntegerRandomInitializer valueInitializer)
        {
            _valueInitializer = valueInitializer;
        }

        public void Operate(ref IntegerVectorGenotype operand)
        {
            if (_valueInitializer == null)
                throw new NullReferenceException();

            if (operand == null)
                throw new ArgumentNullException();

            for (int i = 0; i < operand.Vector.Length; i++)
            {
                _valueInitializer.Operate(ref operand.Vector[i]);
            }
        }
    }

    /// <summary>
    /// Initialize each element of a vector with the given value initializer.
    /// </summary>
    [DataContract(Namespace = "http://numetaheuristics.codeplex.com/schemas")]
    [Export(typeof(IUnaryOperator<BooleanVectorGenotype>))]
    public class BooleanVectorInitializer : IUnaryOperator<BooleanVectorGenotype>
    {
        [DataMember]
        private BooleanRandomInitializer _valueInitializer;

        public BooleanVectorInitializer()
        {
        }

        public BooleanVectorInitializer(BooleanRandomInitializer valueInitializer)
        {
            _valueInitializer = valueInitializer;
        }

        public void Operate(ref BooleanVectorGenotype operand)
        {
            if (_valueInitializer == null)
                throw new NullReferenceException();

            if (operand == null)
                throw new ArgumentNullException();

            for (int i = 0; i < operand.Vector.Length; i++)
            {
                _valueInitializer.Operate(ref operand.Vector[i]);
            }
        }
    }
}
